﻿import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from 'src/users/users.service';
import * as bcrypt from 'bcrypt';
import axios from 'axios';

@Injectable()
export class AuthService {
    constructor(
        private readonly usersService: UsersService,
        private readonly jwtService: JwtService,
    ) { }

    async validateUser(user_name: string, user_password: string): Promise<any> {
        const user = await this.usersService.findOne(user_name);
        if (user && await bcrypt.compare(user_password, user.user_password)) {//验证
            const { user_password, ...result } = user;
            return result;
        }
        return null;
    }

    async login(user: any) {//检索用户并验证密码
        const validateUser = await this.validateUser(user.user_name, user.user_password);
        if (!validateUser) {
            throw new UnauthorizedException();
        }
        return {
            id: validateUser.id,
            user_name: validateUser.user_name,
            identity: validateUser.identity,
            nickname: user.nickname,
            headimgurl: user.headimgurl,
            access_token: this.jwtService.sign({
                user_name: validateUser.user_name,
                identity: validateUser.identity,
                sub: validateUser.id
            })
        };
    }

    async qrCodeLogin(openid: string, access_token: string) {
        const { data: wxUserInfo } = await axios.get('https://api.weixin.qq.com/cgi-bin/user/info', {
            params: {
                access_token,
                openid,
                lang: 'zh_CN'
            }
        });
        const unionid = wxUserInfo.unionid;
        if (unionid) {
            return await this.createOrUpdateUser(unionid);
        }
    }

    async publicLogin(access_token: string, openid: string) {
        const userinfo = await axios.get(`https://api.weixin.qq.com/sns/userinfo`, {
            params: {
                access_token,
                openid,
                lang: 'zh_CN'
            }
        }).then(result => result.data);
        if (!userinfo.errcode) {
            return await this.createOrUpdateUser(userinfo.unionid, userinfo);
        }
    }

    async createOrUpdateUser(unionid: string, userinfo?: any) {
        let user = await this.usersService.findOneByUnionId(unionid);
        if (!user) {
            const res = await this.usersService.create(unionid, userinfo);
            if (res) {
                user = res;
            }
        }
        if (user && (!user.nickname || !user.headimgurl) && userinfo) {
            userinfo.nickname && (user.nickname = userinfo.nickname);
            userinfo.headimgurl && (user.headimgurl = userinfo.headimgurl);
            this.usersService.updateUserinfo(user);
        }
        if (user) {
            return {
                id: user.id,
                user_name: user.user_name,
                identity: user.identity,
                nickname: user.nickname,
                headimgurl: user.headimgurl,
                access_token: this.jwtService.sign({
                    user_name: user.user_name,
                    identity: user.identity,
                    sub: user.id,
                })
            }
        }
    }
}
